import { _decorator, Component, Node, Vec2, Vec3, Graphics, Color, log } from 'cc';
import { GridNode } from '../Scripts/GridNode';
import { AStarPath } from '../Scripts/AStarPath';
const { ccclass, property } = _decorator;

@ccclass('GridMapManager')
export class GridMapManager extends Component {
    @property
    gridSize: number = 40; // 每个格子的大小

    @property
    mapWidth: number = 20; // 地图宽度（格子数）

    @property
    mapHeight: number = 15; // 地图高度（格子数）

    @property(Graphics)
    graphics: Graphics = null; // 用于绘制网格和路径

    private _grid: GridNode[][] = [];
    private _astar: AStarPath = new AStarPath();

    protected onLoad(): void {
        this.initGrid();
        this.drawGrid();
    }

    // 打印所有障碍物位置
    private logObstacles(): void {
        log("===== Current Obstacles =====");
        let obstacleCount = 0;
        for (let y = 0; y < this.mapHeight; y++) {
            for (let x = 0; x < this.mapWidth; x++) {
                if (!this._grid[y][x].walkable) {
                    log(`Obstacle at (${x}, ${y})`);
                    obstacleCount++;
                }
            }
        }
        log(`Total obstacles: ${obstacleCount}`);
        log("==========================");
    }

    // 初始化网格
    private initGrid(): void {
        for (let y = 0; y < this.mapHeight; y++) {
            this._grid[y] = [];
            for (let x = 0; x < this.mapWidth; x++) {
                this._grid[y][x] = new GridNode(x, y, true);
            }
        }
    }

    // 绘制网格
    private drawGrid(): void {
        if (!this.graphics) return;

        this.graphics.clear();
        
        // 设置线条颜色和宽度
        this.graphics.strokeColor = Color.WHITE;
        this.graphics.lineWidth = 1;

        // 绘制横线
        for (let y = 0; y <= this.mapHeight; y++) {
            this.graphics.moveTo(0, y * this.gridSize);
            this.graphics.lineTo(this.mapWidth * this.gridSize, y * this.gridSize);
        }

        // 绘制竖线
        for (let x = 0; x <= this.mapWidth; x++) {
            this.graphics.moveTo(x * this.gridSize, 0);
            this.graphics.lineTo(x * this.gridSize, this.mapHeight * this.gridSize);
        }

        this.graphics.stroke();
    }

    // 获取指定位置的节点
    public getNodeAt(x: number, y: number): GridNode | null {
        if (this.isValidPosition(x, y)) {
            return this._grid[y][x];
        }
        return null;
    }

    // 设置障碍物
    public setWalkable(x: number, y: number, walkable: boolean): void {
        if (this.isValidPosition(x, y)) {
            this._grid[y][x].walkable = walkable;
            this.visualizeObstacle(x, y, !walkable);
            // 每次设置障碍物后打印所有障碍物位置
            this.logObstacles();
        }
    }

    // 切换格子的可通行状态
    public toggleWalkable(x: number, y: number): void {
        if (this.isValidPosition(x, y)) {
            const node = this._grid[y][x];
            const newWalkable = !node.walkable;
            this.setWalkable(x, y, newWalkable);
        }
    }

    // 可视化障碍物
    private visualizeObstacle(x: number, y: number, isObstacle: boolean): void {
        if (!this.graphics) return;

        const px = x * this.gridSize;
        const py = y * this.gridSize;

        if (isObstacle) {
            this.graphics.fillColor = Color.RED;
        } else {
            this.graphics.fillColor = new Color(0, 0, 0, 0); // 透明色
        }

        this.graphics.fillRect(px, py, this.gridSize, this.gridSize);
        this.graphics.stroke();
    }

    // 寻找路径
    public findPath(startPos: Vec2, endPos: Vec2): Vec2[] {
        // 将世界坐标转换为网格坐标
        const startGridPos = this.worldToGrid(startPos);
        const endGridPos = this.worldToGrid(endPos);

        log(`Finding path from (${startGridPos.x}, ${startGridPos.y}) to (${endGridPos.x}, ${endGridPos.y})`);
        this.logObstacles();

        if (!this.isValidPosition(startGridPos.x, startGridPos.y) || 
            !this.isValidPosition(endGridPos.x, endGridPos.y)) {
            log("Invalid start or end position");
            return null;
        }

        const startNode = this._grid[startGridPos.y][startGridPos.x];
        const endNode = this._grid[endGridPos.y][endGridPos.x];

        // 检查起点和终点是否可通行
        if (!startNode.walkable || !endNode.walkable) {
            log("Start or end node is not walkable");
            return null;
        }

        // 获取路径节点
        const pathNodes = this._astar.findPath(startNode, endNode, this._grid);
        if (!pathNodes) {
            log("No path found");
            return null;
        }

        // 直接将路径点转换为世界坐标，不进行平滑处理
        return pathNodes.map(node => this.gridToWorld(new Vec2(node.x, node.y)));
    }

    // 绘制路径
    public drawPath(path: Vec2[]): void {
        if (!this.graphics || !path || path.length < 2) return;

        this.graphics.strokeColor = Color.GREEN;
        this.graphics.lineWidth = 2;

        this.graphics.moveTo(path[0].x, path[0].y);
        for (let i = 1; i < path.length; i++) {
            this.graphics.lineTo(path[i].x, path[i].y);
        }

        this.graphics.stroke();
    }

    // 世界坐标转网格坐标
    public worldToGrid(pos: Vec2): Vec2 {
        return new Vec2(
            Math.floor(pos.x / this.gridSize),
            Math.floor(pos.y / this.gridSize)
        );
    }

    // 网格坐标转世界坐标（返回格子中心点）
    public gridToWorld(gridPos: Vec2): Vec2 {
        return new Vec2(
            (gridPos.x + 0.5) * this.gridSize,
            (gridPos.y + 0.5) * this.gridSize
        );
    }

    // 检查坐标是否有效
    public isValidPosition(x: number, y: number): boolean {
        return x >= 0 && x < this.mapWidth && y >= 0 && y < this.mapHeight;
    }
}